package org.misty.blog.controller;

import org.misty.blog.exception.NotFoundException;
import org.misty.blog.po.Article;
import org.misty.blog.service.ArticleService;
import org.misty.blog.service.CategoryService;
import org.misty.blog.service.TagService;
import org.misty.blog.vo.ArticleQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Optional;

@Controller
public class IndexController {
    private final ArticleService articleService;
    private final CategoryService categoryService;
    private final TagService tagService;

    public IndexController(ArticleService articleService, CategoryService categoryService, TagService tagService) {
        this.articleService = articleService;
        this.categoryService = categoryService;
        this.tagService = tagService;
    }

    @GetMapping("/")
    public String index(
            @PageableDefault(size = 2, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
            Model model) {
        ArticleQuery query = new ArticleQuery();
        query.setPublished(true);
        Page<Article> page = articleService.listArticles(pageable, query);
        model.addAttribute("page", page);
        model.addAttribute("articles", page.getContent());
        model.addAttribute("recommends", articleService.listTop(10));
        model.addAttribute("categories", categoryService.listTop(6));
        model.addAttribute("tags", tagService.listTop(10));
        return "index";
    }

    @RequestMapping("/search")
    public String search(
            @PageableDefault(size = 2, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
            @Nullable @RequestParam String s,
            Model model) {
        ArticleQuery query = new ArticleQuery();
        query.setSearch(s);
        query.setPublished(true);
        Page<Article> page = articleService.listArticles(pageable, query);
        model.addAttribute("search", s);
        model.addAttribute("page", page);
        model.addAttribute("articles", page.getContent());
        return "search";
    }

    @GetMapping("/blog/{id}")
    public String blog(@PathVariable Long id, Model model) {
        Optional<Article> opt = articleService.viewArticle(id);
        opt.orElseThrow(() -> new NotFoundException("文章未找到 " + id));
        model.addAttribute("article", opt.get());
        return "blog";
    }

    @GetMapping("newestArticles")
    public String newestArticles(Model model) {
        model.addAttribute("newestArticles", articleService.listTop(3));
        return "_fragments :: newestArticles";
    }
}
